package com.oraycn.esbasic.helpers;

import android.app.VoiceInteractor;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.PixelFormat;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.media.ExifInterface;
import android.net.Uri;
import android.util.Log;
import android.util.Size;
import java.io.ByteArrayOutputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.ByteBuffer;

import static android.content.ContentValues.TAG;

public class ImageHelper {

    /**
     * 获得圆角图片
     *
     * @param bitmap  图片
     * @param roundPx 圆角的px值
     * @return 带圆角的Bitmap
     */
    public static Bitmap getRoundedCornerBitmap(Bitmap bitmap, float roundPx) {
        int w = bitmap.getWidth();
        int h = bitmap.getHeight();
        Bitmap output = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
        Canvas canvas = new Canvas(output);
        final int color = 0xff424242;
        final Paint paint = new Paint();
        final Rect rect = new Rect(0, 0, w, h);
        final RectF rectF = new RectF(rect);
        paint.setAntiAlias(true);
        canvas.drawARGB(0, 0, 0, 0);
        paint.setColor(color);
        canvas.drawRoundRect(rectF, roundPx, roundPx, paint);
        paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
        canvas.drawBitmap(bitmap, rect, rect, paint);
        return output;
    }

    /**
     * 将Bitmap转化为Drawable
     *
     * @param bitmap
     * @param context
     */
    public static Drawable bitmapToDrawable(Bitmap bitmap, Context context) {
        BitmapDrawable drawbale = new BitmapDrawable(context.getResources(),
                bitmap);
        return drawbale;
    }

    /**
     * byte数组转bitmap
     * @param data
     * @return
     */
    public static Bitmap byteArrayToBitmap(byte[] data)
    {
       return  BitmapFactory.decodeByteArray(data,0,data.length, new BitmapFactory.Options());
    }

    /**
     * 将Drawable转化为Bitmap
     *
     * @param drawable
     */
    public static Bitmap drawableToBitmap(Drawable drawable) {
        // 取 drawable 的长宽
        int w = drawable.getIntrinsicWidth();
        int h = drawable.getIntrinsicHeight();

        // 取 drawable 的颜色格式
        Bitmap.Config config = drawable.getOpacity() != PixelFormat.OPAQUE ? Bitmap.Config.ARGB_8888
                : Bitmap.Config.RGB_565;
        // 建立对应 bitmap
        Bitmap bitmap = Bitmap.createBitmap(w, h, config);
        // 建立对应 bitmap 的画布
        Canvas canvas = new Canvas(bitmap);
        drawable.setBounds(0, 0, w, h);
        // 把 drawable 内容画到画布中
        drawable.draw(canvas);
        return bitmap;
    }


    /**
     * 读取图片的旋转的角度
     *
     * @param path 图片绝对路径
     * @return 图片的旋转角度
     */
    public static int getBitmapDegree(String path) {
        int degree = 0;
        try {
            // 从指定路径下读取图片，并获取其EXIF信息
            ExifInterface exifInterface = new ExifInterface(path);
            // 获取图片的旋转信息
            int orientation = exifInterface.getAttributeInt(ExifInterface.TAG_ORIENTATION,
                    ExifInterface.ORIENTATION_NORMAL);
            switch (orientation) {
                case ExifInterface.ORIENTATION_ROTATE_90:
                    degree = 90;
                    break;
                case ExifInterface.ORIENTATION_ROTATE_180:
                    degree = 180;
                    break;
                case ExifInterface.ORIENTATION_ROTATE_270:
                    degree = 270;
                    break;
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return degree;
    }

    /**
     * 获取(旋转后的)照片信息
     * @param path
     * @return
     */
    public static Bitmap getRotateBitmap(String path)
    {
        int degree =getBitmapDegree(path);
        Bitmap bmp =BitmapFactory.decodeFile(path);
        return rotateBitmapByDegree(bmp,degree);
    }

    /**
     * 将图片按照某个角度进行旋转
     *
     * @param bm     需要旋转的图片
     * @param degree 旋转角度
     * @return 旋转后的图片
     */
    private static Bitmap rotateBitmapByDegree(Bitmap bm, int degree) {
        Bitmap returnBm = null;

        // 根据旋转角度，生成旋转矩阵
        Matrix matrix = new Matrix();
        matrix.postRotate(degree);
        try {
            // 将原始图片按照旋转矩阵进行旋转，并得到新的图片
            returnBm = Bitmap.createBitmap(bm, 0, 0, bm.getWidth(), bm.getHeight(), matrix, true);
        } catch (OutOfMemoryError e) {
        }
        if (returnBm == null) {
            returnBm = bm;
        }

        if (bm != null && bm != returnBm) {
            bm.recycle();
        }

        return returnBm;
    }

    /**
     * 根据路径获取图片的尺码(旋转后的)
     *
     * @param pathName ：源图片资源
     * @return 图片的Size
     */
    public static Size getImgSize(String pathName) {
        BitmapFactory.Options options = new BitmapFactory.Options();
        /**
         * 最关键在此，把options.inJustDecodeBounds = true;
         * 这里再decodeFile()，返回的bitmap为空，但此时调用options.outHeight时，已经包含了图片的高了
         */
        options.inJustDecodeBounds = true;
        BitmapFactory.decodeFile(pathName, options);
        ExifInterface exif = null;
        try {
            exif = new ExifInterface(pathName);
        } catch (IOException e) {
            e.printStackTrace();
            exif = null;
        }
        Size size=new Size(options.outWidth,options.outHeight);
        if (exif != null) {
            // 读取图片中相机方向信息
            int ori = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION,
                    ExifInterface.ORIENTATION_UNDEFINED);
            // 计算旋转角度
            switch (ori) {
                case ExifInterface.ORIENTATION_ROTATE_90:
                case ExifInterface.ORIENTATION_ROTATE_270:
                    size=new Size(options.outHeight,options.outWidth);
                    break;
                default:
                    break;
            }
        }
        return size;
    }

    /**
     * 获取网络图片的大小
     * @param imgUrl
     * @return
     */
    public static  Size getUrlImgSize(String imgUrl) {
        HttpURLConnection connection;
        InputStream inputStream;
        try {
            connection = (HttpURLConnection) new URL(imgUrl).openConnection();
            inputStream = connection.getInputStream();
            Size size = getImageSize(inputStream);
            inputStream.close();
            return size;
        } catch (IOException e) {
            e.printStackTrace();
            return new Size(0, 0);
        }
    }

    private static Size getImageSize(InputStream is) {
        BitmapFactory.Options options = new BitmapFactory.Options();
        options.inJustDecodeBounds = true;
        BitmapFactory.decodeStream(is, null, options);
        return new Size(options.outWidth,options.outHeight);
    }

    /**
     * 获取图片的指定最大长度的尺寸
     *
     * @param bitmap    ：源图片资源
     * @param maxLength ：图片长、宽最大的长度  单位:px
     * @return 图片的Size
     */
    public static Size getZoomSize(Bitmap bitmap, int maxLength) {
        int imgWidth = bitmap.getWidth();
        int imgHeight = bitmap.getHeight();
        return getZoomSize(imgWidth, imgHeight, maxLength);
    }

    /**
     * 获取图片的指定最大长度的尺寸
     *
     * @param imgWidth  ：源宽度
     * @param imgHeight ：源长度
     * @param maxLength ：图片长、宽最大的长度  单位:px
     * @return 图片的Size
     */
    public static Size getZoomSize(int imgWidth, int imgHeight, int maxLength) {
        if (maxLength <= 0) {
            return new Size(0, 0);
        }
        int width = imgWidth, height = imgHeight;
        if (imgWidth > maxLength && imgHeight > maxLength) {
            if (imgWidth > imgHeight) {
                width = maxLength;
                height = (int) (imgHeight * width / imgWidth);
            } else {
                height = maxLength;
                width = (int) (imgWidth * height / imgHeight);
            }
        } else if (imgWidth > maxLength) {
            width = maxLength;
            height = (int) (imgHeight * width / imgWidth);
        } else if (imgHeight > maxLength) {
            height = maxLength;
            width = (int) (imgWidth * height / imgHeight);
        }
        return new Size(width, height);
    }


    /**
     * 获取Drawable的缩放
     *
     * @param drawable
     * @param w        缩放后的宽度 （单位px）
     * @param h        缩放后的高度 （单位px）
     */
    public static Drawable getZoomDrawable(Drawable drawable, int w, int h) {
        int width = drawable.getIntrinsicWidth();
        int height = drawable.getIntrinsicHeight();
        // drawable转换成bitmap
        Bitmap oldbmp = drawableToBitmap(drawable);
        // 创建操作图片用的Matrix对象
        Matrix matrix = new Matrix();
        // 计算缩放比例
        float sx = ((float) w / width);
        float sy = ((float) h / height);
        // 设置缩放比例
        matrix.postScale(sx, sy);
        // 建立新的bitmap，其内容是对原bitmap的缩放后的图
        Bitmap newbmp = Bitmap.createBitmap(oldbmp, 0, 0, width, height,
                matrix, true);
        return new BitmapDrawable(newbmp);
    }

    /**
     * 图片的缩放方法
     *
     * @param bitmap  ：源图片资源
     * @param maxSize ：图片允许最大空间  单位:KB
     * @return
     */
    public static Bitmap getZoomImage(Bitmap bitmap, double maxSize) {
        if (null == bitmap) {
            return null;
        }
        if (bitmap.isRecycled()) {
            return null;
        }

        // 单位：从 Byte 换算成 KB
        double currentSize = bitmapToByteArray(bitmap, false).length / 1024;
        // 判断bitmap占用空间是否大于允许最大空间,如果大于则压缩,小于则不压缩
        while (currentSize > maxSize) {
            // 计算bitmap的大小是maxSize的多少倍
            double multiple = currentSize / maxSize;
            // 开始压缩：将宽带和高度压缩掉对应的平方根倍
            // 1.保持新的宽度和高度，与bitmap原来的宽高比率一致
            // 2.压缩后达到了最大大小对应的新bitmap，显示效果最好
            bitmap = getZoomImage(bitmap, bitmap.getWidth() / Math.sqrt(multiple), bitmap.getHeight() / Math.sqrt(multiple), true);
            currentSize = bitmapToByteArray(bitmap, false).length / 1024;
        }
        return bitmap;
    }

    /**
     * 图片的缩放方法
     *
     * @param orgBitmap ：源图片资源
     * @param newWidth  ：缩放后宽度
     * @param newHeight ：缩放后高度
     * @return
     */
    public static Bitmap getZoomImage(Bitmap orgBitmap, double newWidth, double newHeight, boolean needRecycle) {
        if (null == orgBitmap) {
            return null;
        }
        if (orgBitmap.isRecycled()) {
            return null;
        }
        if (newWidth <= 0 || newHeight <= 0) {
            return null;
        }

        // 获取图片的宽和高
        float width = orgBitmap.getWidth();
        float height = orgBitmap.getHeight();
        // 创建操作图片的matrix对象
        Matrix matrix = new Matrix();
        // 计算宽高缩放率
        float scaleWidth = ((float) newWidth) / width;
        float scaleHeight = ((float) newHeight) / height;
        if(scaleWidth==1&&scaleHeight==1)
        {
            return orgBitmap;
        }
        // 缩放图片动作
        matrix.postScale(scaleWidth, scaleHeight);
        Bitmap newBitmap = Bitmap.createBitmap(orgBitmap, 0, 0, (int) width, (int) height, matrix, true);//若scaleWidth、scaleHeight都是1，创建的图和原图是同一对象，而不是新的一个对象
        if (!orgBitmap.isRecycled() && needRecycle) {
            orgBitmap.recycle();
        }
        return newBitmap;
    }


    /**
     * 获取图片的缩放后压缩的byte[]
     *
     * @param orgBitmap   ：源图片资源
     * @param newWidth    ：缩放后宽度
     * @param newHeight   ：缩放后高度
     * @param needRecycle : orgBitmap是否需要回收
     * @return
     */
    public static byte[] getZoomImageToByteArray(Bitmap orgBitmap, double newWidth, double newHeight, boolean needRecycle) {
        Bitmap bitmap = getZoomImage(orgBitmap, newWidth, newHeight, needRecycle);
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        try {
            bitmap.compress(Bitmap.CompressFormat.PNG, 70, outputStream);
        } finally {
            try {
                outputStream.close();
            } catch (IOException ioe) {
                Log.e(TAG, ioe.toString());
            }
        }
        return outputStream.toByteArray();
    }

    /**
     * 获取图片的原始核心数据
     * @param bitmap
     * @return
     */
    public static byte[] getRGBA24CoreData(Bitmap bitmap)
    {
        ByteBuffer buf = ByteBuffer.allocate(bitmap.getByteCount());
        bitmap.copyPixelsToBuffer(buf);
        return buf.array();
    }

    /**
     * bitmap转换成byte[]（压缩后）
     *
     * @param bitmap
     * @param needRecycle 原bitmap是否需要回收
     * @return
     */
    public static byte[] bitmapToByteArray(Bitmap bitmap, boolean needRecycle) {
        return bitmapToByteArray(bitmap, 100, needRecycle);
    }

    public static byte[] bitmapToByteArray(Bitmap bitmap, int quality, boolean needRecycle) {
        return bitmapToByteArray(bitmap, Bitmap.CompressFormat.JPEG, quality, needRecycle);
    }

    public static byte[] bitmapToByteArray(Bitmap bitmap, Bitmap.CompressFormat format, int quality, boolean needRecycle) {
        if (null == bitmap) {
            return null;
        }
        if (bitmap.isRecycled()) {
            return null;
        }
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        bitmap.compress(format, quality, baos);
        if (needRecycle && bitmap != null) {
            bitmap.recycle();
        }

        byte[] result = baos.toByteArray();
        try {
            baos.close();
        } catch (Exception e) {
            Log.e(TAG, e.toString());
        }
        return result;
    }

    /**
     * Uri转换成byte[]
     *
     * @param context
     * @param uri     原bitmap回收
     * @return
     */
    public static byte[] filePathToByteArray(Context context, Uri uri) {
        if (uri == null || uri.getPath().length() == 0) {
            return null;
        }
        Bitmap bitmap = null;
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        try {
            bitmap = BitmapFactory.decodeStream(context.getContentResolver().openInputStream(uri));
            bitmap.compress(Bitmap.CompressFormat.PNG, 100, baos);
            baos.close();
        } catch (FileNotFoundException e) {
            Log.e(TAG, e.getMessage());
        } catch (IOException ee) {
            Log.e(TAG, ee.getMessage());
        } finally {
            if (bitmap != null) {
                bitmap.recycle();
            }
        }
        return baos.toByteArray();
    }

    /**
     * 从给定路径加载图片
     */
    public static Bitmap loadBitmap(String imgpath) {
        return BitmapFactory.decodeFile(imgpath);
    }


    /**
     * 从给定的路径加载图片，并指定是否自动旋转方向
     */
    public static Bitmap loadBitmap(String imgpath, boolean adjustOritation) {
        if (!adjustOritation) {
            return loadBitmap(imgpath);
        } else {
            Bitmap bm = loadBitmap(imgpath);
            int digree = 0;
            ExifInterface exif = null;
            try {
                exif = new ExifInterface(imgpath);
            } catch (IOException e) {
                e.printStackTrace();
                exif = null;
            }
            if (exif != null) {
                // 读取图片中相机方向信息
                int ori = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION,
                        ExifInterface.ORIENTATION_UNDEFINED);
                // 计算旋转角度
                switch (ori) {
                    case ExifInterface.ORIENTATION_ROTATE_90:
                        digree = 90;
                        break;
                    case ExifInterface.ORIENTATION_ROTATE_180:
                        digree = 180;
                        break;
                    case ExifInterface.ORIENTATION_ROTATE_270:
                        digree = 270;
                        break;
                    default:
                        digree = 0;
                        break;
                }
            }
            if (digree != 0) {
                // 旋转图片
                Matrix m = new Matrix();
                m.postRotate(digree);
                bm = Bitmap.createBitmap(bm, 0, 0, bm.getWidth(),
                        bm.getHeight(), m, true);
            }
            return bm;
        }
    }
}